from agile.models import Project, Sprint, Task, TaskSearchCriteria, Scrum, Comment, Repository, Revision
from agile.forms import SprintForm, ProjectForm, TaskForm, TaskSearchCriteriaForm, ProjectSearchCriteriaForm, SprintSearchCriteriaForm,  ScrumForm,  CommentForm, CommentDeleteForm
from agile.forms import RepositorySearchCriteriaForm, RepositoryForm, UserUsernameForm,UserFirstnameForm,UserLastnameForm,UserEmailForm
#from django.contrib.auth.views import password_reset
from django.contrib.auth.decorators import login_required
from django.template import RequestContext
from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404, render
from django.contrib.auth import authenticate, login, logout
from django.http import HttpResponse, HttpResponseRedirect
from datetime import datetime, timedelta, date, time
from django.db.models import Q
import time as time2

def auth(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(username=username, password=password)
        if user is not None and user.is_active:
            login(request,user)
            return render_to_response('index.html', {'username':request.user.username,})
        else:
            return HttpResponse("Login failed.", content_type="text/plain")
    else:
        return render_to_response('login.html', context_instance=RequestContext(request))

@login_required
def index(request):
    return render_to_response('index.html', {'username':request.user.username,})

@login_required
def projects(request):
    criteria = ProjectSearchCriteriaForm(request.GET)
    projects = Project.objects.filter(**criteria.get_param_dict())
    return render_to_response('projects.html', {'projects': projects, 'criteria':criteria})

@login_required
def scrums(request):
    scrums = Scrum.objects.all()
    return render_to_response('scrums.html', {'scrums': scrums})

@login_required
def scrum_view(request, pid):
    if not request.user.has_perm('agile.view_scrum'):
        return HttpResponse("You don't have view permissions.")
    scrum = get_object_or_404(Scrum, pk=pid)
    form = ScrumForm(instance=scrum, read_only=True)
    return render_to_response('scrum.html', {'scrum': form,
                                               'editable': False,
                                               'id': pid})

@login_required
def project_view(request, pid):
    if not request.user.has_perm('agile.view_project'):
        return HttpResponse("You don't have view permissions.")
    project = get_object_or_404(Project, pk=pid)
    form = ProjectForm(instance=project, read_only=True)
    return render_to_response('project.html', {'project': form,
                                               'editable': False,
                                               'id': pid})

@login_required
def project_edit(request, pid):
    project = get_object_or_404(Project, pk=pid)
    if not request.user.has_perm('agile.change_project'):
        return HttpResponse("You don't have edit permissions.")
    if not request.user.has_perm('agile.view_project'):
        return HttpResponse("You don't have view permissions.")
    if request.method == 'POST':
        form = ProjectForm(request.POST, instance=project)
        if form.is_valid():
            form.save()
            return render_to_response('project_saved.html', {'project': form})
    else:
        form = ProjectForm(instance=project) 
    return render(request, 'project.html', {'project': form,
                                               'editable': True,
                                               'id': pid})


@login_required
def project_delete(request, pid):
    project = get_object_or_404(Project, pk=pid)
    if not request.user.has_perm('agile.delete_project'):
        return HttpResponse("You don't have delete permissions.")
    if not request.user.has_perm('agile.change_project'):
        return HttpResponse("You don't have edit permissions.")
    if request.method == 'POST':
        form = ProjectForm(instance=project, read_only=True)
        project.delete()
        return render_to_response('project_delete.html', {'project': form})
    else:    
        form = ProjectForm(instance=project, read_only=True)       
    return render(request, 'project.html', {'project': form,
                                               'deletable': True,
                                               'id': pid})
@login_required
def confirm_project_delete(request, pid):
    if not request.user.has_perm('agile.delete_project'):
        return HttpResponse("You don't have delete permissions.")
    if not request.user.has_perm('agile.change_project'):
        return HttpResponse("You don't have edit permissions.")
    project = get_object_or_404(Project, pk=pid)
    sprints = project.sprint_set.all
    tasks = project.task_set.all
    if request.method == 'POST':
        project_delete(request, pid)
        return render_to_response('project_delete.html')
    return render(request, 'confirm_project_delete.html', {'project':project, 'sprints':sprints, 'tasks':tasks})
    
@login_required
def confirm_sprint_delete(request, pid):
    if not request.user.has_perm('agile.delete_sprint'):
        return HttpResponse("You don't have delete permissions.")
    if not request.user.has_perm('agile.change_sprint'):
        return HttpResponse("You don't have edit permissions.")
    sprint = get_object_or_404(Sprint, pk=pid)
    tasks = sprint.task_set.all
    if request.method == 'POST':
        sprint_delete(request, pid)
        return render_to_response('sprint_delete.html')
    return render(request, 'confirm_sprint_delete.html', {'sprint':sprint, 'tasks':tasks})
                               
@login_required
def scrum_delete(request, pid):
    scrum = get_object_or_404(Scrum, pk=pid)
    if not request.user.has_perm('agile.delete_scrum'):
        return HttpResponse("You don't have delete permissions.")
    if not request.user.has_perm('agile.change_scrum'):
        return HttpResponse("You don't have edit permissions.")
    if request.method == 'POST':
        #form = ScrumDeleteForm(instance=scrum)
        form = ScrumForm(instance=scrum, read_only=True)
        scrum.delete()
        return render_to_response('scrum_delete.html', {'scrum': form})
    else:
        #form = ScrumDeleteForm(instance=scrum)  
        form = ScrumForm(instance=scrum, read_only=True)           
    return render(request, 'scrum.html', {'scrum': form,
                                               'deletable': True,
                                               'id': pid})

@login_required
def comment_delete(request, pid):
    comment = get_object_or_404(Comment, pk=pid)
    taskid = comment.tasks.pk
    if not request.user.has_perm('agile.delete_comment'):
        return HttpResponse("You don't have delete permissions.")
    if not request.user.has_perm('agile.change_comment'):
        return HttpResponse("You don't have edit permissions.")
    if request.method == 'POST':
        form = CommentDeleteForm(instance=comment)
        comment.delete()
        return render_to_response('comment_delete.html', {'comment': form, 'taskid': taskid})
    else:
        form = CommentDeleteForm(instance=comment)           
    return render(request, 'comment_change.html', {'comment': form,
                                               'deletable': True,
                                               'taskid': taskid})

@login_required
def scrum_new(request):
    if not request.user.has_perm('agile.add_scrum'):
        return HttpResponse("You don't have permission to create a new scrum.")
    if request.method == 'POST':
        form = ScrumForm(request.POST)
        if form.is_valid():
            form.save()
            return render_to_response('scrum_saved.html', {'scrum': form})
    else:
        form = ScrumForm()
    return render(request, 'scrum.html', {'scrum': form,
                                               'editable': True,
                                               'id': None})
    
@login_required
def project_new(request):
    if not request.user.has_perm('agile.add_project'):
        return HttpResponse("You don't have permission to create a new project.")
    if request.method == 'POST':
        form = ProjectForm(request.POST)
        if form.is_valid():
            form.save()
            return render_to_response('project_saved.html', {'project': form})
    else:
        form = ProjectForm()
    return render(request, 'project.html', {'project': form,
                                               'editable': True,
                                               'id': None})
    

@login_required
def sprints(request):
    criteria = SprintSearchCriteriaForm(request.GET)
    sprints = Sprint.objects.filter(**criteria.get_param_dict())
    return render_to_response('sprints.html', {'sprints' : sprints, 'criteria':criteria})

@login_required
def sprint_view(request, pid):
    if not request.user.has_perm('agile.view_sprint'):
        return HttpResponse("You don't have view permissions.")
    sprint = get_object_or_404(Sprint, pk=pid)
    form = SprintForm(instance=sprint, read_only=True)
    return render_to_response('sprint.html', {'sprint': form,
                                               'editable': False,
                                               'id': pid})

@login_required
def scrum_edit(request, pid):
    scrum = get_object_or_404(Scrum, pk=pid)
    if not request.user.has_perm('agile.change_scrum'):
        return HttpResponse("You don't have edit permissions.")
    if not request.user.has_perm('agile.view_scrum'):
        return HttpResponse("You don't have view permissions.")
    if request.method == 'POST':
        form = ScrumForm(request.POST, instance=scrum)
        if form.is_valid():
            form.save()
            return render_to_response('scrum_saved.html', {'scrum': form})
    else:
        form = ScrumForm(instance=scrum) 
    return render(request, 'scrum.html', {'scrum': form,
                                               'editable': True,
                                               'id': pid})

@login_required
def sprint_edit(request, pid):
    sprint = get_object_or_404(Sprint, pk=pid)
    if not request.user.has_perm('agile.change_sprint'):
        return HttpResponse("You don't have edit permissions.")
    if not request.user.has_perm('agile.view_sprint'):
        return HttpResponse("You don't have view permissions.")
    if request.method == 'POST':
        form = SprintForm(request.POST, instance=sprint)
        if form.is_valid():
            form.save()
            return render_to_response('sprint_save.html', {'sprint': form})
    else:
        form = SprintForm(instance=sprint) 
    return render(request, 'sprint.html', {'sprint': form,
                                               'editable': True,
                                               'id': pid})


@login_required
def sprint_delete(request, pid):
    sprint = get_object_or_404(Sprint, pk=pid)
    if not request.user.has_perm('agile.delete_project'):
        return HttpResponse("You don't have delete permissions.")
    if not request.user.has_perm('agile.change_project'):
        return HttpResponse("You don't have edit permissions.")
    if request.method == 'POST':
        #form = SprintDeleteForm(instance=sprint)
        form = SprintForm(instance=sprint, read_only=True)  
        sprint.delete()
        return render_to_response('sprint_delete.html', {'sprint': form})
    else:
        #form = SprintDeleteForm(instance=sprint)    
        form = SprintForm(instance=sprint, read_only=True)         
    return render(request, 'sprint.html', {'sprint': form,
                                               'deletable': True,
                                               'id': pid})                   
    
@login_required
def sprint_new(request):
    if not request.user.has_perm('agile.add_sprint'):
        return HttpResponse("You don't have permission to create a new sprint.")
    if request.method == 'POST':
        form = SprintForm(request.POST)
        if form.is_valid():
            form.save()
            return render_to_response('sprint_save.html', {'sprint': form})
    else:
        form = SprintForm()
    return render(request, 'sprint.html', {'sprint': form,
                                               'editable': True,
                                               'id': None})

@login_required 
def tasks(request, cid = None):
    uids = None
    if request.method == 'POST':
        criteria = TaskSearchCriteriaForm(request.POST)
        if criteria.is_valid():
            crit_model = criteria.save(commit=False)
            crit_model.owner = request.user
            crit_model.save()
            criteria.save()
            return render_to_response('criteria_saved.html', {'criteria' : criteria})
        else:
            return HttpResponse('invalid %s' % criteria.errors)
    elif cid == None:
        criteria = TaskSearchCriteriaForm(request.GET)
        criteria.is_valid()
        if 'users' in request.GET:
            uids = [user for user in request.GET.getlist('users')]
    else:
        cid = int(cid)
        crit_model = get_object_or_404(TaskSearchCriteria, pk=cid)
        if crit_model.owner != request.user:
            return HttpResponse('You may not use another users search criteria.')
        criteria = TaskSearchCriteriaForm(instance=crit_model)
    tasks = Task.objects.filter(**criteria.instance.get_param_dict(uids=uids))
    crits = TaskSearchCriteria.objects.filter(owner=request.user)
    return render(request, 'tasks.html', {'tasks' : tasks, 'criteria': criteria, 'saved': crits, 'cid': cid})

@login_required
def task_view(request,pid):
    if not request.user.has_perm('agile.view_task'):
        return HttpResponse("You don't have view permissions.")
    task = get_object_or_404(Task,pk=pid)
    comments = Comment.objects.filter(tasks=pid)
    children = Task.objects.filter(parent=task)
    revisions = Revision.objects.filter(repo__project=task.project).order_by('-number')
    if not request.user.has_perm('agile.view_task'):
        users = task.users.all()
        usertest = False
        for user in users:
            if user == request.user:
                usertest = True
        if not usertest:
            return HttpResponse("You don't have view permissions")
    form = TaskForm(instance=task , read_only=True)
    return render(request,'task.html', {'task':form,
                                        'editable':False,
                                        'id':int(pid),
                                        'children': children,
                                        'revisions':revisions,
                                        'comments':comments})

@login_required
def comment_edit(request,pid):
    comment = get_object_or_404(Comment,pk=pid)
    taskid = comment.tasks.pk
    if not request.user.has_perm('agile.change_comment'):
        if not comment.user == request.user:
            return HttpResponse("You don't have edit permissions")
    if not request.user.has_perm('agile.view_comment'):
        if not comment.user == request.user:
            return HttpResponse("You don't have view permissions")
    if request.method == 'POST':
        form = CommentForm(request.POST,instance=comment)
        if form.is_valid():
            form.save()
            return render_to_response('comment_save.html',{'comment':form, 'taskid': taskid})
    else:
        form = CommentForm(instance=comment)
    return render(request,'comment_change.html',{'comment':form,'editable':True, 'taskid':taskid})

@login_required
def task_edit(request,pid):
    task = get_object_or_404(Task,pk=pid)
    comments = Comment.objects.filter(tasks=pid)
    children = Task.objects.filter(parent=task)
    revisions = Revision.objects.filter(repo__project=task.project).order_by('-number')
    if not request.user.has_perm('agile.change_task'):
        users = task.users.all()
        usertest = False
        for user in users:
            if user == request.user:
                usertest = True
        if not usertest:
            return HttpResponse("You don't have edit permissions")
    if not request.user.has_perm('agile.view_task'):
        users = task.users.all()
        usertest = False
        for user in users:
            if user == request.user:
                usertest = True
        if not usertest:
            return HttpResponse("You don't have view permissions")
    if request.method == 'POST':
        form = TaskForm(request.POST,instance=task)
        if form.is_valid():
            form.save()
            return render_to_response('task_save.html',{'task':form})
    else:
        form = TaskForm(instance=task)
    return render(request,'task.html',{'task':form,
                                       'editable':True, 
                                       'id':int(pid),
                                       'children':children,
                                       'revisions':revisions,
                                       'comments':comments})

@login_required
def comment_post(request):
    comment = Comment()
    comment.user = request.user
    tid = request.POST.get('task')
    comment.tasks = get_object_or_404(Task,pk=tid)
    text = request.POST.get('content')
    comment.contents = text
    comment.time = datetime.now()
    comment.save()
    return HttpResponseRedirect("/task/view/%s" % tid)

@login_required
def task_delete(request, pid):
    task = get_object_or_404(Task, pk=pid)
    comments = Comment.objects.filter(tasks=pid)
    children = Task.objects.filter(parent=task)
    revisions = Revision.objects.filter(repo__project=task.project).order_by('-number')
    if not request.user.has_perm('agile.delete_task'):
        return HttpResponse("You don't have delete permissions.")
    if not request.user.has_perm('agile.change_task'):
        return HttpResponse("You don't have view permissions.")
    if request.method == 'POST':
        form = TaskForm(instance=task, read_only=True)
        task.delete()
        return render_to_response('task_delete.html', {'task': form})
    else:
        form = TaskForm(instance=task, read_only=True)
    return render(request, 'task.html', {'task': form,
                  'deletable': True,
                  'id': int(pid),
                  'children':children,
                  'revisions':revisions,
                  'comments':comments})

@login_required
def task_new(request):
    if not request.user.has_perm('agile.add_task'):
        return HttpResponse("You don't have permission to create a new task.")
    if request.method == 'POST':
        form = TaskForm(request.POST)
        if form.is_valid():
            form.save()
            return render_to_response('task_save.html', {'task': form})
    else:
        form = TaskForm()
    return render(request, 'task.html', {'task': form,
                  'editable': True,
                  'id': None})

@login_required
def repositorys(request):
    criteria = RepositorySearchCriteriaForm(request.GET)
    repos = Repository.objects.filter(**criteria.get_param_dict())
    return render_to_response('repos.html', {'criteria': criteria, 'repos': repos})

@login_required
def repository_view(request, pid):
    if not request.user.has_perm('agile.view_repository'):
        return HttpResponse('You do not have permissions to view repositorys')
    repo = get_object_or_404(Repository, pk=pid)
    revisions = Revision.objects.filter(repo__id=pid).order_by('-number')
    form = RepositoryForm(instance=repo, read_only=True)
    return render_to_response('repo.html', {'repo': form, 'revisions': revisions, 'editable' : False, 'deletable': False, 'id' : pid})

@login_required
def repository_edit(request, pid):
    if not request.user.has_perm('agile.view_repository'):
        return HttpResponse('You do not have permissions to view repositorys')
    if not request.user.has_perm('agile.change_repository'):
        return HttpResponse('You do not have permissions to edit repositorys')
    repo = get_object_or_404(Repository, pk=pid)
    revisions = Revision.objects.filter(repo__id=pid).order_by('-number')
    if request.method == 'POST':
        form = RepositoryForm(request.POST, instance=repo)
        if form.is_valid():
            form.save()
            return render_to_response('repo_saved.html', {'repo': form})
    else:
        form = RepositoryForm(instance=repo)
    return render(request, 'repo.html', {'repo': form, 'revisions': revisions, 'editable' : True, 'deletable': False, 'id' : pid})

@login_required
def repository_new(request):
    if not request.user.has_perm('agile.add_repository'):
        return HttpResponse('You do not have permissions to add a repository')
    if request.method == 'POST':
        form = RepositoryForm(request.POST)
        if form.is_valid():
            form.save()
            return render_to_response('repo_saved.html', {'repo': form})
    else:
        form = RepositoryForm()
    return render(request, 'repo.html', {'repo': form, 'editable' : True, 'deletable': False})

@login_required
def repository_delete(request, pid):
    if not request.user.has_perm('agile.view_repository'):
        return HttpResponse('You do not have permissions to view repositorys')
    if not request.user.has_perm('agile.delete_repository'):
        return HttpResponse('You do not have permissions to delete repositorys')
    repo = get_object_or_404(Repository, pk=pid)
    revisions = Revision.objects.filter(repo__id=pid).order_by('-number')
    if request.method == 'POST':
        form = RepositoryForm(instance=repo)
        repo.delete()
        return render_to_response('repo_delete.html', {'repo': form})
    else:
        form = RepositoryForm(instance=repo, read_only=True)
    return render(request, 'repo.html', {'repo': form, 'revisions': revisions, 'editable' : False, 'deletable': True, 'id' : pid})
    
    
@login_required
def logout_view(request):
    logout(request)
    return HttpResponseRedirect('/')

@login_required
def calendar(request):
    start = datetime.fromtimestamp(int(request.GET.get('start')))
    end = datetime.fromtimestamp(int(request.GET.get('end')))
    day_adv = timedelta(1)
    week_adv = timedelta(7)
    sprints_final = Sprint.objects.filter((Q(startDate__gte = start) & Q(startDate__lte = end)) | 
                                          (Q(endDate__gte = start) & Q(endDate__lte = end)), users__in=[request.user.pk,])
    data = '['
    for sprint in sprints_final:
        data += '{"title":"%s", "start":%d, "end":%d, "allDay":true, "url":"/sprint/view/%s"}' % (sprint.name, time2.mktime(sprint.startDate.timetuple()), time2.mktime(sprint.endDate.timetuple()), sprint.pk)
        data += ','
        for scrum in Scrum.objects.all():
            if scrum.sprint == sprint:
                scrumdate = datetime.combine(sprint.startDate, scrum.time)
                while scrumdate.weekday() != scrum.day:
                    scrumdate += day_adv
                while scrumdate.date() <= sprint.endDate:
                    data += '{"title":"%s", "start":%d, "allDay":false, "color":"#780000", "url":"/scrum/view/%s"}' % (scrum.name, time2.mktime(scrumdate.timetuple()), scrum.pk)
                    data += ','
                    scrumdate += week_adv     
    data_final = data.rstrip(',')
    data_final += ']'
    return HttpResponse(data_final, mimetype='application/json')   

@login_required
def user_view(request):
    if not request.user.has_perm('agile.view_user'):
        return HttpResponse("You don't have user view permissions.")
    if not request.user.has_perm('agile.change_user'):
        return HttpResponse("You don't have user edit permissions.")
    user = request.user
    return render(request, 'user.html', {'user':user})


@login_required
def user_password_properties(request):
   
    user = request.user
    
    return render(request, 'user_password.html', {'user':user})

@login_required
def user_edit_properties(request, edit=""):
    if not request.user.has_perm('agile.view_user'):
        return HttpResponse("You don't have user view permissions.")
    if not request.user.has_perm('agile.change_user'):
        return HttpResponse("You don't have user edit permissions.")
    profile = request.user
    if edit =="username":
        form = UserUsernameForm(request.POST or None, instance=profile)
        if request.method == 'POST': # If the form has been submitted...
            if form.is_valid(): 
                form.save()
                return HttpResponseRedirect('/users/properties_settings_changed/') # Redirect after POST
            else:
                return HttpResponse("Form is invalid.")
    
    
    elif edit =="first_name":
        form = UserFirstnameForm(request.POST or None, instance=profile)
        print 'Point A'
        if request.method == 'POST': # If the form has been submitted...
            print 'Point B'
            if form.is_valid(): 
               # profile.first_name = request.POST.get('first_name')
                #profile.save()
                #print 'saved'
                form.save()
                return HttpResponseRedirect('/users/properties_settings_changed/') # Redirect after POST
            else:
                return HttpResponse("Form is invalid.")
    elif edit =="last_name":
        form = UserLastnameForm(request.POST or None, instance=profile)
        if request.method == 'POST': # If the form has been submitted...
       
            if form.is_valid(): 
                form.save()
                return HttpResponseRedirect('/users/properties_settings_changed/') # Redirect after POST
            else:
                return HttpResponse("Form is invalid.")
    elif edit =="email":
        form = UserEmailForm(request.POST or None, instance=profile)
        if request.method == 'POST': # If the form has been submitted...       
            if form.is_valid(): 
                form.save()
                return HttpResponseRedirect('/users/properties_settings_changed/') # Redirect after POST
            else:
                return HttpResponse("Form is invalid.")        
        
    else:
    
        form = UserEmailForm(request.POST or None, instance=profile)
        if request.method == 'POST': # If the form has been submitted...
            if form.is_valid(): 
                form.save()
                return HttpResponseRedirect('/users/properties_settings_changed/') # Redirect after POST
            else:
                return HttpResponse("Form is invalid.")
    return render(request, 'user_edit.html', {'form': form}) #RETURNS unbound form

@login_required
def user_settings_changed(request):
   
    user = request.user
    
    return render(request, 'user_properties_changed.html', {'user':user})
